home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 405_01 / flexpp / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-04  |  18.2 KB  |  931 lines

  1. /* misc - miscellaneous flex routines */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. #ifndef lint
  30. static char rcsid[] =
  31.     "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/misc.c,v 2.9 90/08/14 00:10:24 vern Exp $ (LBL)";
  32. #endif
  33.  
  34. #include <ctype.h>
  35. #include "flexdef.h"
  36.  
  37.  
  38. /* ANSI C does not guarantee that isascii() is defined */
  39. #ifndef isascii
  40. #define isascii(c) ((c) <= 0177)
  41. #endif
  42.  
  43.  
  44.  
  45. /* declare functions that have forward references */
  46.  
  47. void dataflush PROTO(());
  48. int otoi PROTO((Char []));
  49.  
  50.  
  51.  
  52. /* allocate_array - allocate memory for an integer array of the given size */
  53.  
  54. void *allocate_array( size, element_size )
  55. int size, element_size;
  56.  
  57.     {
  58.     register void *mem;
  59.  
  60.     /* on 16-bit int machines (e.g., 80286) we might be trying to
  61.      * allocate more than a signed int can hold, and that won't
  62.      * work.  Cheap test:
  63.      */
  64.     if ( element_size * size <= 0 )
  65.         flexfatal( "request for < 1 byte in allocate_array()" );
  66.  
  67.     mem = (void *) malloc( (unsigned) (element_size * size) );
  68.  
  69.     if ( mem == NULL )
  70.     flexfatal( "memory allocation failed in allocate_array()" );
  71.  
  72.     return ( mem );
  73.     }
  74.  
  75.  
  76. /* all_lower - true if a string is all lower-case
  77.  *
  78.  * synopsis:
  79.  *    Char *str;
  80.  *    int all_lower();
  81.  *    true/false = all_lower( str );
  82.  */
  83.  
  84. int all_lower( str )
  85. register Char *str;
  86.  
  87.     {
  88.     while ( *str )
  89.     {
  90.     if ( ! isascii( *str ) || ! islower( *str ) )
  91.         return ( 0 );
  92.     ++str;
  93.     }
  94.  
  95.     return ( 1 );
  96.     }
  97.  
  98.  
  99. /* all_upper - true if a string is all upper-case
  100.  *
  101.  * synopsis:
  102.  *    Char *str;
  103.  *    int all_upper();
  104.  *    true/false = all_upper( str );
  105.  */
  106.  
  107. int all_upper( str )
  108. register Char *str;
  109.  
  110.     {
  111.     while ( *str )
  112.     {
  113.     if ( ! isascii( *str ) || ! isupper( (char) *str ) )
  114.         return ( 0 );
  115.     ++str;
  116.     }
  117.  
  118.     return ( 1 );
  119.     }
  120.  
  121.  
  122. /* bubble - bubble sort an integer array in increasing order
  123.  *
  124.  * synopsis
  125.  *   int v[n], n;
  126.  *   bubble( v, n );
  127.  *
  128.  * description
  129.  *   sorts the first n elements of array v and replaces them in
  130.  *   increasing order.
  131.  *
  132.  * passed
  133.  *   v - the array to be sorted
  134.  *   n - the number of elements of 'v' to be sorted */
  135.  
  136. void bubble( v, n )
  137. int v[], n;
  138.  
  139.     {
  140.     register int i, j, k;
  141.  
  142.     for ( i = n; i > 1; --i )
  143.     for ( j = 1; j < i; ++j )
  144.         if ( v[j] > v[j + 1] )    /* compare */
  145.         {
  146.         k = v[j];    /* exchange */
  147.         v[j] = v[j + 1];
  148.         v[j + 1] = k;
  149.         }
  150.     }
  151.  
  152.  
  153. /* clower - replace upper-case letter to lower-case
  154.  *
  155.  * synopsis:
  156.  *    Char clower();
  157.  *    int c;
  158.  *    c = clower( c );
  159.  */
  160.  
  161. Char clower( c )
  162. register int c;
  163.  
  164.     {
  165.     return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c );
  166.     }
  167.  
  168.  
  169. /* copy_string - returns a dynamically allocated copy of a string
  170.  *
  171.  * synopsis
  172.  *    char *str, *copy, *copy_string();
  173.  *    copy = copy_string( str );
  174.  */
  175.  
  176. char *copy_string( str )
  177. register char *str;
  178.  
  179.     {
  180.     register char *c;
  181.     char *copy;
  182.  
  183.     /* find length */
  184.     for ( c = str; *c; ++c )
  185.     ;
  186.  
  187.     copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
  188.  
  189.     if ( copy == NULL )
  190.     flexfatal( "dynamic memory failure in copy_string()" );
  191.  
  192.     for ( c = copy; (*c++ = *str++); )
  193.     ;
  194.  
  195.     return ( copy );
  196.     }
  197.  
  198.  
  199. /* copy_unsigned_string -
  200.  *    returns a dynamically allocated copy of a (potentially) unsigned string
  201.  *
  202.  * synopsis
  203.  *    Char *str, *copy, *copy_unsigned_string();
  204.  *    copy = copy_unsigned_string( str );
  205.  */
  206.  
  207. Char *copy_unsigned_string( str )
  208. register Char *str;
  209.  
  210.     {
  211.     register Char *c;
  212.     Char *copy;
  213.  
  214.     /* find length */
  215.     for ( c = str; *c; ++c )
  216.     ;
  217.  
  218.     copy = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) );
  219.  
  220.     if ( copy == NULL )
  221.     flexfatal( "dynamic memory failure in copy_unsigned_string()" );
  222.  
  223.     for ( c = copy; (*c++ = *str++); )
  224.     ;
  225.  
  226.     return ( copy );
  227.     }
  228.  
  229.  
  230. /* cshell - shell sort a character array in increasing order
  231.  *
  232.  * synopsis
  233.  *
  234.  *   Char v[n];
  235.  *   int n, special_case_0;
  236.  *   cshell( v, n, special_case_0 );
  237.  *
  238.  * description
  239.  *   does a shell sort of the first n elements of array v.
  240.  *   If special_case_0 is true, then any element equal to 0
  241.  *   is instead assumed to have infinite weight.
  242.  *
  243.  * passed
  244.  *   v - array to be sorted
  245.  *   n - number of elements of v to be sorted
  246.  */
  247.  
  248. void cshell( v, n, special_case_0 )
  249. Char v[];
  250. int n, special_case_0;
  251.  
  252.     {
  253.     int gap, i, j, jg;
  254.     Char k;
  255.  
  256.     for ( gap = n / 2; gap > 0; gap = gap / 2 )
  257.     for ( i = gap; i < n; ++i )
  258.         for ( j = i - gap; j >= 0; j = j - gap )
  259.         {
  260.         jg = j + gap;
  261.  
  262.         if ( special_case_0 )
  263.             {
  264.             if ( v[jg] == 0 )
  265.             break;
  266.  
  267.             else if ( v[j] != 0 && v[j] <= v[jg] )
  268.             break;
  269.             }
  270.  
  271.         else if ( v[j] <= v[jg] )
  272.             break;
  273.  
  274.         k = v[j];
  275.         v[j] = v[jg];
  276.         v[jg] = k;
  277.         }
  278.     }
  279.  
  280.  
  281. /* dataend - finish up a block of data declarations
  282.  *
  283.  * synopsis
  284.  *    dataend();
  285.  */
  286.  
  287. void dataend()
  288.  
  289.     {
  290.     if ( datapos > 0 )
  291.     dataflush();
  292.  
  293.     /* add terminator for initialization */
  294.     puts( "    } ;\n" );
  295.  
  296.     dataline = 0;
  297.     datapos = 0;
  298.     }
  299.  
  300.  
  301.  
  302. /* dataflush - flush generated data statements
  303.  *
  304.  * synopsis
  305.  *    dataflush();
  306.  */
  307.  
  308. void dataflush()
  309.  
  310.     {
  311.     putchar( '\n' );
  312.  
  313.     if ( ++dataline >= NUMDATALINES )
  314.     {
  315.     /* put out a blank line so that the table is grouped into
  316.      * large blocks that enable the user to find elements easily
  317.      */
  318.     putchar( '\n' );
  319.     dataline = 0;
  320.     }
  321.  
  322.     /* reset the number of characters written on the current line */
  323.     datapos = 0;
  324.     }
  325.  
  326.  
  327. /* flexerror - report an error message and terminate
  328.  *
  329.  * synopsis
  330.  *    char msg[];
  331.  *    flexerror( msg );
  332.  */
  333.  
  334. void flexerror( msg )
  335. char msg[];
  336.  
  337.     {
  338.     fprintf( stderr, "%s: %s\n", program_name, msg );
  339.  
  340.     flexend( 1 );
  341.     }
  342.  
  343.  
  344. /* flexfatal - report a fatal error message and terminate
  345.  *
  346.  * synopsis
  347.  *    char msg[];
  348.  *    flexfatal( msg );
  349.  */
  350.  
  351. void flexfatal( msg )
  352. char msg[];
  353.  
  354.     {
  355.     fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg );
  356.     exit( 1 );
  357.     }
  358.  
  359.  
  360. /* flex_gettime - return current time
  361.  *
  362.  * synopsis
  363.  *    char *flex_gettime(), *time_str;
  364.  *    time_str = flex_gettime();
  365.  *
  366.  * note
  367.  *    the routine name has the "flex_" prefix because of name clashes
  368.  *    with Turbo-C
  369.  */
  370.  
  371. /* include sys/types.h to use time_t and make lint happy */
  372.  
  373. #ifndef MS_DOS
  374. #ifndef VMS
  375. #include <sys/types.h>
  376. #else
  377. #include <types.h>
  378. #endif
  379. #endif
  380.  
  381. #ifdef MS_DOS
  382. #include <time.h>
  383. #endif
  384.  
  385. char *flex_gettime()
  386.  
  387.     {
  388.     time_t t, time();
  389.     char *result, *ctime(), *copy_string();
  390.  
  391.     t = time( (long *) 0 );
  392.  
  393.     result = copy_string( ctime( &t ) );
  394.  
  395.     /* get rid of trailing newline */
  396.     result[24] = '\0';
  397.  
  398.     return ( result );
  399.     }
  400.  
  401.  
  402. /* lerrif - report an error message formatted with one integer argument
  403.  *
  404.  * synopsis
  405.  *    char msg[];
  406.  *    int arg;
  407.  *    lerrif( msg, arg );
  408.  */
  409.  
  410. void lerrif( msg, arg )
  411. char msg[];
  412. int arg;
  413.  
  414.     {
  415.     char errmsg[MAXLINE];
  416.     (void) sprintf( errmsg, msg, arg );
  417.     flexerror( errmsg );
  418.     }
  419.  
  420.  
  421. /* lerrsf - report an error message formatted with one string argument
  422.  *
  423.  * synopsis
  424.  *    char msg[], arg[];
  425.  *    lerrsf( msg, arg );
  426.  */
  427.  
  428. void lerrsf( msg, arg )
  429. char msg[], arg[];
  430.  
  431.     {
  432.     char errmsg[MAXLINE];
  433.  
  434.     (void) sprintf( errmsg, msg, arg );
  435.     flexerror( errmsg );
  436.     }
  437.  
  438.  
  439. /* htoi - convert a hexadecimal digit string to an integer value
  440.  *
  441.  * synopsis:
  442.  *    int val, htoi();
  443.  *    Char str[];
  444.  *    val = htoi( str );
  445.  */
  446.  
  447. int htoi( str )
  448. Char str[];
  449.  
  450.     {
  451.     int result;
  452.  
  453.     (void) sscanf( (char *) str, "%x", &result );
  454.  
  455.     return ( result );
  456.     }
  457.  
  458.  
  459. /* is_hex_digit - returns true if a character is a valid hex digit, false
  460.  *          otherwise
  461.  *
  462.  * synopsis:
  463.  *    int true_or_false, is_hex_digit();
  464.  *    int ch;
  465.  *    val = is_hex_digit( ch );
  466.  */
  467.  
  468. int is_hex_digit( ch )
  469. int ch;
  470.  
  471.     {
  472.     if ( isdigit( ch ) )
  473.     return ( 1 );
  474.  
  475.     switch ( clower( ch ) )
  476.     {
  477.     case 'a':
  478.     case 'b':
  479.     case 'c':
  480.     case 'd':
  481.     case 'e':
  482.     case 'f':
  483.         return ( 1 );
  484.  
  485.     default:
  486.         return ( 0 );
  487.     }
  488.     }
  489.  
  490.  
  491. /* line_directive_out - spit out a "# line" statement */
  492.  
  493. void line_directive_out( output_file_name )
  494. FILE *output_file_name;
  495.  
  496.     {
  497.     if ( infilename && gen_line_dirs )
  498.       {char *p;
  499.         fprintf( output_file_name, "#line %d \"",linenum);
  500.         for(p=infilename;*p;p++)
  501.           if(*p=='"' || *p=='\\') fprintf(output_file_name,"\\%c",*p);
  502.           else if(!isprint(*p)) fprintf(output_file_name,"\\%3.3o",*p);
  503.           else fprintf(output_file_name,"%c",*p);
  504.         fprintf( output_file_name,"\"\n");
  505.       }
  506.     }
  507.  
  508.  
  509. /* mk2data - generate a data statement for a two-dimensional array
  510.  *
  511.  * synopsis
  512.  *    int value;
  513.  *    mk2data( value );
  514.  *
  515.  *  generates a data statement initializing the current 2-D array to "value"
  516.  */
  517. void mk2data( value )
  518. int value;
  519.  
  520.     {
  521.     if ( datapos >= NUMDATAITEMS )
  522.     {
  523.     putchar( ',' );
  524.     dataflush();
  525.     }
  526.  
  527.     if ( datapos == 0 )
  528.     /* indent */
  529.     fputs( "    ", stdout );
  530.  
  531.     else
  532.     putchar( ',' );
  533.  
  534.     ++datapos;
  535.  
  536.     printf( "%5d", value );
  537.     }
  538.  
  539.  
  540. /* mkdata - generate a data statement
  541.  *
  542.  * synopsis
  543.  *    int value;
  544.  *    mkdata( value );
  545.  *
  546.  *  generates a data statement initializing the current array element to
  547.  *  "value"
  548.  */
  549. void mkdata( value )
  550. int value;
  551.  
  552.     {
  553.     if ( datapos >= NUMDATAITEMS )
  554.     {
  555.     putchar( ',' );
  556.     dataflush();
  557.     }
  558.  
  559.     if ( datapos == 0 )
  560.     /* indent */
  561.     fputs( "    ", stdout );
  562.  
  563.     else
  564.     putchar( ',' );
  565.  
  566.     ++datapos;
  567.  
  568.     printf( "%5d", value );
  569.     }
  570.  
  571.  
  572. /* myctoi - return the integer represented by a string of digits
  573.  *
  574.  * synopsis
  575.  *    Char array[];
  576.  *    int val, myctoi();
  577.  *    val = myctoi( array );
  578.  *
  579.  */
  580.  
  581. int myctoi( array )
  582. Char array[];
  583.  
  584.     {
  585.     int val = 0;
  586.  
  587.     (void) sscanf( (char *) array, "%d", &val );
  588.  
  589.     return ( val );
  590.     }
  591.  
  592.  
  593. /* myesc - return character corresponding to escape sequence
  594.  *
  595.  * synopsis
  596.  *    Char array[], c, myesc();
  597.  *    c = myesc( array );
  598.  *
  599.  */
  600.  
  601. Char myesc( array )
  602. Char array[];
  603.  
  604.     {
  605.     Char c, esc_char;
  606.     register int sptr;
  607.  
  608.     switch ( array[1] )
  609.     {
  610. #ifdef __STDC__
  611.     case 'a': return ( '\a' );
  612. #endif
  613.     case 'b': return ( '\b' );
  614.     case 'f': return ( '\f' );
  615.     case 'n': return ( '\n' );
  616.     case 'r': return ( '\r' );
  617.     case 't': return ( '\t' );
  618.     case 'v': return ( '\v' );
  619.  
  620.     case '0':
  621.     case '1':
  622.     case '2':
  623.     case '3':
  624.     case '4':
  625.     case '5':
  626.     case '6':
  627.     case '7':
  628.     case '8':
  629.     case '9':
  630.         { /* \<octal> */
  631.         sptr = 1;
  632.  
  633.         while ( isascii( array[sptr] ) && isdigit( array[sptr] ) )
  634.         /* don't increment inside loop control because if
  635.          * isdigit() is a macro it might expand into multiple
  636.          * increments ...
  637.          */
  638.         ++sptr;
  639.  
  640.         c = array[sptr];
  641.         array[sptr] = '\0';
  642.  
  643.         esc_char = otoi( array + 1 );
  644.  
  645.         array[sptr] = c;
  646.  
  647.         return ( esc_char );
  648.         }
  649.  
  650.     case 'x':
  651.         { /* \x<hex> */
  652.         int sptr = 2;
  653.  
  654.         while ( isascii( array[sptr] ) && is_hex_digit( array[sptr] ) )
  655.         /* don't increment inside loop control because if
  656.          * isdigit() is a macro it might expand into multiple
  657.          * increments ...
  658.          */
  659.         ++sptr;
  660.  
  661.         c = array[sptr];
  662.         array[sptr] = '\0';
  663.  
  664.         esc_char = htoi( array + 2 );
  665.  
  666.         array[sptr] = c;
  667.  
  668.         return ( esc_char );
  669.         }
  670.  
  671.     default:
  672.         return ( array[1] );
  673.     }
  674.     }
  675.  
  676.  
  677. /* otoi - convert an octal digit string to an integer value
  678.  *
  679.  * synopsis:
  680.  *    int val, otoi();
  681.  *    Char str[];
  682.  *    val = otoi( str );
  683.  */
  684.  
  685. int otoi( str )
  686. Char str[];
  687.  
  688.     {
  689.     int result;
  690.  
  691.     (void) sscanf( (char *) str, "%o", &result );
  692.  
  693.     return ( result );
  694.     }
  695.  
  696.  
  697. /* readable_form - return the the human-readable form of a character
  698.  *
  699.  * synopsis:
  700.  *    int c;
  701.  *    char *readable_form();
  702.  *    <string> = readable_form( c );
  703.  *
  704.  * The returned string is in static storage.
  705.  */
  706.  
  707. char *readable_form( c )
  708. register int c;
  709.  
  710.     {
  711.     static char rform[10];
  712.  
  713.     if ( (c >= 0 && c < 32) || c >= 127 )
  714.     {
  715.     switch ( c )
  716.         {
  717.         case '\n': return ( "\\n" );
  718.         case '\t': return ( "\\t" );
  719.         case '\f': return ( "\\f" );
  720.         case '\r': return ( "\\r" );
  721.         case '\b': return ( "\\b" );
  722.  
  723.         default:
  724.         (void) sprintf( rform, "\\%.3o", c );
  725.         return ( rform );
  726.         }
  727.     }
  728.  
  729.     else if ( c == ' ' )
  730.     return ( "' '" );
  731.  
  732.     else
  733.     {
  734.     rform[0] = c;
  735.     rform[1] = '\0';
  736.  
  737.     return ( rform );
  738.     }
  739.     }
  740.  
  741.  
  742. /* reallocate_array - increase the size of a dynamic array */
  743.  
  744. void *reallocate_array( array, size, element_size )
  745. void *array;
  746. int size, element_size;
  747.  
  748.     {
  749.     register void *new_array;
  750.  
  751.     /* same worry as in allocate_array(): */
  752.     if ( size * element_size <= 0 )
  753.         flexfatal( "attempt to increase array size by less than 1 byte" );
  754.  
  755.     new_array =
  756.     (void *) realloc( (char *)array, (unsigned) (size * element_size ));
  757.  
  758.     if ( new_array == NULL )
  759.     flexfatal( "attempt to increase array size failed" );
  760.  
  761.     return ( new_array );
  762.     }
  763.  
  764. /* any_skelout - write out one section of any skeleton  file
  765.  *
  766.  * synopsis
  767.  *    any_skelout(FILE *theskel,FILE *thefile,int *thecounter,char *thename,int use_name,int *back_lf);
  768.  *
  769.  * DESCRIPTION
  770.  *    Copies from theskel to thefile until a line beginning with a single or more "%" or
  771.  *    EOF is found.
  772.  * convert @ to the value of lexer_name in name_defined!=0 and use_name!=0
  773.  * generate comments and #line (#line only if thecounter!=NULL and  *back_lf!=1)
  774.  * back_lf indicate that the last characters where backslash-newline
  775.  * and it forbide #line because #line are not accepted in macro defs
  776.  * do nothing if thefile==NULL
  777.  */
  778. void any_skelout(theskel,thefile,thecounter,thename,use_name,back_lf)
  779. FILE *theskel,*thefile;
  780. int *thecounter;
  781. char *thename;
  782. int use_name;
  783. int *back_lf;
  784. {int ch;
  785.  int col=0;
  786.  if(thefile==0 ) 
  787.    return;
  788.  if ( gen_line_dirs && thecounter!=(int *)0 && thename !=NULL && *back_lf!=1)
  789.        {char *p;
  790.         fprintf( thefile, "#line %d \"",*thecounter);
  791.         for(p=thename;*p;p++)
  792.           if(*p=='"' || *p=='\\') fprintf(thefile,"\\%c",*p);
  793.           else if(!isprint(*p)) fprintf(thefile,"\\%3.3o",*p);
  794.            else fprintf(thefile,"%c",*p);
  795.         fprintf( thefile,"\"\n");
  796.       }
  797.  while((ch=getc(theskel))!=EOF)
  798.   {col++;
  799.    if(ch=='\\') *back_lf=-1;
  800.    else if(ch=='\n' && *back_lf==-1) *back_lf=1;
  801.    else if(ch=='%' && *back_lf==1) *back_lf=1;
  802.    else *back_lf=0;
  803.    if(ch=='@' && use_name) 
  804.      {if(name_defined==0)
  805.         { fprintf(thefile,"@Undefined_name@");
  806.           if(thecounter!=(int *)0 && thename !=NULL)
  807.             fprintf( stderr, "bad skeleton: %s, line %d\n", thename, *thecounter );
  808.           flexfatal("@ found in skeleton before %%name \n");
  809.         }
  810.       else fprintf(thefile,"%s",lexer_name);
  811.      }
  812.    else if(ch=='\n')
  813.      { putc(ch,thefile);
  814.        col=0;
  815.        if(thecounter!=(int *)0)
  816.           (*thecounter)++;}
  817.    else if(col==1 && ch=='%') 
  818.      {fprintf(thefile,"/* ");
  819.       while((ch=getc(theskel))!=EOF && ch!='\n') 
  820.          putc(ch,thefile);
  821.       fprintf(thefile," */ %s\n",(*back_lf==1)?"\\":"");  /* use \\\n to continue macros def */
  822.       if(thecounter!=(int *)0)
  823.           (*thecounter)++;
  824.       return;
  825.       }
  826.    else putc(ch,thefile);
  827.   };
  828. }
  829. /* action_out - write the actions from the temporary file to lex.yy.c
  830.  *
  831.  * synopsis
  832.  *     action_out();
  833.  *
  834.  *     Copies the action file up to % (or end-of-file) to lex.yy.c
  835.  */
  836.  
  837. void action_out()
  838.  
  839. {static int bklf=0;
  840.  any_skelout(temp_action_file,stdout,(int *)0,(char *)0,0,&bklf);
  841. }
  842.  
  843.  
  844. /* skelout - write out one section of the skeleton file
  845.  *
  846.  * synopsis
  847.  *    skelout();
  848.  *
  849.  * DESCRIPTION
  850.  *    Copies from skelfile to stdout until a line beginning with "%" or
  851.  *    EOF is found.... 
  852.  */
  853. void skelout()
  854. {static int skel_line=1,bklf=0;
  855.  any_skelout(skelfile,stdout,&skel_line,skelname,1,&bklf);
  856. }
  857. /* header_skeleton_out - write out one section of the skeleton header file
  858.  *
  859.  * synopsis
  860.  *    header_skeleton_out();
  861.  *
  862.  * DESCRIPTION
  863.  *    Copies from skelheaderfile to headerfile until a line beginning with a single or more "%" or
  864.  *    EOF is found....
  865.  * convert ...
  866.  */
  867.  
  868. void header_skeleton_out()
  869. {static int hskel_line=1,bklf=0;
  870.      any_skelout(skelheaderfile,headerfile,&hskel_line,skelheaderfilename,1,&bklf);
  871.     }
  872.  
  873. /* transition_struct_out - output a yy_trans_info structure
  874.  *
  875.  * synopsis
  876.  *     int element_v, element_n;
  877.  *     transition_struct_out( element_v, element_n );
  878.  *
  879.  * outputs the yy_trans_info structure with the two elements, element_v and
  880.  * element_n.  Formats the output with spaces and carriage returns.
  881.  */
  882.  
  883. void transition_struct_out( element_v, element_n )
  884. int element_v, element_n;
  885.  
  886.     {
  887.     printf( "%7d, %5d,", element_v, element_n );
  888.  
  889.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  890.  
  891.     if ( datapos >= 75 )
  892.     {
  893.     putchar( '\n' );
  894.  
  895.     if ( ++dataline % 10 == 0 )
  896.         putchar( '\n' );
  897.  
  898.     datapos = 0;
  899.     }
  900.     }
  901.  
  902. /* set lexer name. check redefinition. */
  903. /* if name==NULL and not yet defined use default value as if defined */
  904. /* include section of sheader skeleton if definition made */
  905. void set_lexer_name(name)
  906. char *name;
  907. {if(name==NULL)
  908.    {
  909.     if(name_defined==0)
  910.      {name_defined++;
  911.       fprintf( stderr,"No %%name given before line %d . Assuming %%name %s\n",
  912.                  linenum, lexer_name );
  913.      } else return;
  914.     }
  915.   else if(name_defined)
  916.     {synerr( "Multiple %%name declaration" );return;}
  917.   else 
  918.    {strncpy(lexer_name,name,sizeof(lexer_name)-1);
  919.     name_defined++;
  920.    }
  921.  fprintf(stdout,"#define YY_%s_FLEX_SCANNER\n",lexer_name);
  922.  if ( ddebug )
  923.    fprintf(headerfile, "#define YY_%s_FLEX_DEBUG\n",lexer_name );
  924.  
  925.  if ( csize == 256 )
  926.    fprintf(headerfile, "#define YY_%s_CHAR unsigned char\n",lexer_name );
  927.  else
  928.    fprintf(headerfile, "#define YY_%s_CHAR char\n",lexer_name );
  929.  header_skeleton_out();
  930. }
  931.